#include <iostream>
#include <future>
#include <vector>
#include <mutex>

#include "thread_pool_1.h"

using namespace std;

namespace test1 {

class Printer {
 public:
  Printer()  = default;
  ~Printer() = default;

  void Print(int i) {
    {
      std::lock_guard<std::mutex> lock(mutex_);
      cout << "Printer::Print i=" << i << endl;
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
  }

 private:
  std::mutex mutex_;
};

void test() {
  ThreadPool_1 pool;
  pool.Start();
  std::vector<std::future<int>> results;

  auto la = [&](int i) {
    std::cout << "hello " << i << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "world " << i << std::endl;
    return i * i;
  };

  for (int i = 0; i < 23; ++i) {
    // results.emplace_back(pool.Submit([i]() {
    //  std::cout << "hello " << i << std::endl;
    //  std::this_thread::sleep_for(std::chrono::seconds(1));
    //  std::cout << "world " << i << std::endl;
    //  return i * i;
    //}));
    results.emplace_back(pool.SubmitWithRet(la, i));
  }

  Printer p;
  for (int i = 0; i < 200; ++i) {
    if (i == 100) {
      std::this_thread::sleep_for(std::chrono::seconds(20));
    }
    pool.Submit(&Printer::Print, &p, i);
  }

  for (auto &&result : results) {
    std::cout << "result " << result.get() << ' ';
  }
  std::cout << std::endl;

  int count = 0;

  while (count < 20) {
    std::cout << pool.PrintState().c_str() << std::endl;
    pool.OnMainThreadTick();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    ++count;
  }
  pool.Stop();
}
}  // namespace test1

int main() {
  test1::test();
  return 0;
}
